unit EncryDecryTool;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils,PJQ,Windows,regexpr;
procedure EncryFile(const inputfile,outfile:string;const ignore:string='');
procedure DecryFile(const inputfile,outfile:string;const ignore:string='');
implementation
{$region '拷贝文件'}
{procedure CopyFile(const SourcePath, DestPath: string);
begin
  try
    // 拷贝文件
    TFile.Copy(SourcePath, DestPath, True);
    // 第三个参数为 True 表示如果目标文件已存在，则覆盖它
    // 如果为 False，则当目标文件已存在时，会抛出异常
  except
    on E: Exception do
      // 处理异常，例如显示错误信息
      ShowMessage('拷贝文件时发生错误: ' + E.Message);
  end;
end;}
{$endregion}

{$region '检测字符串是否匹配指定正则表达式'}
function checkStrHas(const str,exp:string):boolean;
var
  Rgr:TRegExpr;
begin
  Result:=False;
  try
    Rgr:=TRegExpr.Create;
    Rgr.Expression:=exp;
    Result:=Rgr.Exec(str);
  finally
    Rgr.Free;
  end;
end;
{$endregion}

{$region '获取文件名'}
function GetFileName(path: string): string;
begin
  Result :=StringReplace(path,ExtractFilePath(path),'',[rfReplaceAll]);
end;
{$endregion}

{$region '加密文件'}
procedure EncryFile(const inputfile,outfile:string;const ignore:string='');
var
FileStream,outFileStream: TFileStream;
key:String;
stream:TStream;
KeyBytes:Array[0..7] of Byte;
i:integer;
begin
  if FileExists(inputfile) then
  begin
    if ignore<>'' then
      begin
        if checkStrHas(inputfile,ignore) then
          begin
            //CopyFile(inputfile,outfile);
            CopyFile(PChar(inputfile), PChar(outfile), True);
            exit;
          end;
      end;
    FileStream := TFileStream.Create(inputfile, fmOpenread);
    key:= CreateKey();
    stream:=EncryStream(FileStream,key);
    FileStream.Free;
    for i := 0 to 7 do
      KeyBytes[i]:=Byte(key[i+1]);
    outFileStream:=TFileStream.Create(outfile,fmCreate);
    outFileStream.Position:=0;
    stream.Position:=0;
    outFileStream.write(KeyBytes, Length(KeyBytes));
    i:=outFileStream.CopyFrom(stream,stream.Size);
    //ShowMessage(inttostr(i));
    stream.Free;
    outFileStream.Free;
  end;
end;
{$endregion}

{$region '解密文件'}
(**
* inputfile 输入文件路径
* outfile   输出文件路径
* ignore    忽略的文件
*)
procedure DecryFile(const inputfile,outfile:String;const ignore:string='');
var
  FileStream,outFileStream: TFileStream;
  key:AnsiString;
  stream:TMemoryStream;
  buff:Array[0..7] of Byte;
  i:integer;
begin
  if FileExists(inputfile) then
  begin
    if ignore<>'' then
      begin
        if checkStrHas(inputfile,ignore) then
          begin
            //CopyFile(inputfile,outfile);
            CopyFile(PChar(inputfile), PChar(outfile), True);
            exit;
          end;
      end;
    FileStream := TFileStream.Create(inputfile, fmOpenread or fmShareDenyRead);
    FileStream.Position:=0;
    FileStream.Read(buff[0],8);
    SetLength(key, 8);
    Move(buff[0], key[1], 8);
    stream:=TMemoryStream.Create;
    stream.CopyFrom(FileStream,FileStream.Size-8);
    DecryStream(Stream,key);
    FileStream.Free;

    outFileStream:=TFileStream.Create(outfile,fmCreate);
    outFileStream.Position:=0;
    stream.Position:=0;
    //outFileStream.write(KeyBytes, Length(KeyBytes));
    outFileStream.CopyFrom(stream,stream.Size);
    //ShowMessage(inttostr(i));
    stream.Free;
    outFileStream.Free;
  end;
end;
{$endregion}

function CreateDecryFileName(path: string):String;
var
  FilePath,FileName,name,tem_name:String;
  i:integer;
begin
  FilePath:=ExtractFilePath(path);
  FileName:=GetFileName(path);
  i:=LastDelimiter('.',FileName);
  name:=LeftStr(FileName,i-1);
  tem_name:=LeftStr(FileName,i-5);
  //FileName:=StringReplace(FileName,name,tem_name+'_dec',[rfReplaceAll]);
  Result:= FilePath+FileName;
end;

end.

